package com.hzncc.flowable_diboot.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.core.holder.ThreadLocalHolder;
import com.diboot.core.service.impl.BaseServiceImpl;
import com.diboot.core.util.BeanUtils;
import com.diboot.core.util.S;
import com.diboot.iam.util.IamSecurityUtils;
import com.diboot.tenant.entity.IamTenant;
import com.diboot.tenant.mapper.IamTenantMapper;
import com.hzncc.flowable_diboot.entity.Customer;
import com.hzncc.flowable_diboot.entity.SalesGroupContent;
import com.hzncc.flowable_diboot.entity.SapCustomer;
import com.hzncc.flowable_diboot.interfacelog.annotation.InterfaceLog;
import com.hzncc.flowable_diboot.mapper.SapCustomerMapper;
import com.hzncc.flowable_diboot.service.CustomerService;
import com.hzncc.flowable_diboot.service.SalesGroupContentService;
import com.hzncc.flowable_diboot.service.SapCustomerService;
import com.hzncc.flowable_diboot.util.SapUtil;
import com.hzncc.flowable_diboot.vo.SapCustomerDetailVO;
import com.hzncc.flowable_diboot.vo.SapCustomerEditVO;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.JCoParameterList;
import com.sap.conn.jco.JCoStructure;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


/**
 * SAP客户 相关Service实现类
 *
 * @author MyName
 * @version 1.0
 * @date 2024-05-27
 * Copyright © MyCorp
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SapCustomerServiceImpl extends BaseServiceImpl<SapCustomerMapper, SapCustomer> implements SapCustomerService {

    private final CustomerService customerService;
    private final SalesGroupContentService salesGroupContentService;
    private final SapUtil sapUtil;
    private final IamTenantMapper iamTenantMapper;


    /**
     * 创建sap客户
     *
     * @param param
     * @throws JCoException
     */
    @Override
    public String createSapCustomer(Map<String, Object> param) throws JCoException {
        // 销售组织目录
        List<Map<String, Object>> salesGroups = (List<Map<String, Object>>) param.get("salesGroups");
        IamTenant tenant = iamTenantMapper.selectById(IamSecurityUtils.getCurrentTenantId());
        // 过滤出当前租户的销售组织
        salesGroups = salesGroups.stream().filter(e -> S.equals(StrUtil.toString(e.get("salesGroup")), tenant.getOrgId())).toList();
        for (Map<String, Object> salesGroup : salesGroups) {
            List<Map<String, Object>> list = new ArrayList<>();
            list.add(salesGroup);
            param.put("salesGroups",list);
            String s = innerCreateSapCustomer(param);
            if (!s.startsWith("S")){
                return s;
            }
        }
        return "S:创建成功";
    }

    @InterfaceLog(code = "SAP_CUSTOMER", name = "SAP客户",direction = "CRM -> SAP")
    public String innerCreateSapCustomer(Map<String, Object> param) throws JCoException {
        Map<String, Object> sap = (Map<String, Object>) param.get("sap");
        Map<String, Object> cusMap = (Map<String, Object>) param.get("customer");
        // 销售组织目录
        List<Map<String, Object>> salesGroups = (List<Map<String, Object>>) param.get("salesGroups");
        salesGroups.forEach(e -> e.put("BUKRS", sap.get("BUKRS")));
        if (sap.get("KUNNR") != null) {
            String res = freezeSapCustomer(salesGroups, sap);
            if (res.startsWith("E")) {
                return res;
            }
            boolean allFreeze = salesGroups.stream().allMatch(e -> S.equals(StrUtil.toString(e.get("isFreeze")), "1"));
            if (allFreeze) {
                List<SalesGroupContent> salesGroupContents = BeanUtils.convertMap2BeanList(salesGroups, SalesGroupContent.class);
                SapCustomer sapCustomer = BeanUtils.convertMap2Bean(cusMap, SapCustomer.class);
                createSapCustomer(sap, sapCustomer);
                createOrUpdateEntity(sapCustomer);
                salesGroupContentService.createOrUpdateEntities(salesGroupContents);
                return res;
            } else {
                List<SalesGroupContent> freezeList = BeanUtils.convertMap2BeanList(salesGroups.stream().filter(e -> S.equals(StrUtil.toString(e.get("isFreeze")), "1")).collect(Collectors.toList()), SalesGroupContent.class);
                salesGroupContentService.createOrUpdateEntities(freezeList);
                salesGroups = salesGroups.stream().filter(e -> !S.equals(StrUtil.toString(e.get("isFreeze")), "1")).collect(Collectors.toList());
            }
        }
        cusMap.put("type", "create");
        sap.put("BZIRK", S.join(salesGroups.stream().map(e -> e.get("salesArea")).collect(Collectors.toList())));
        JCoParameterList exe = sapUtil.exe("ZFSD003", sap, cusMap);
        String customerId = param.get("customId").toString(); // 客户id
        Customer customer = new Customer();
        customer.setId(customerId);
        JCoStructure exMessage = exe.getStructure("EX_MESSAGE");
        String resType = exMessage.getString("MSGTYPE");
        String kunnr = exMessage.getString("KUNNR");
        String msgtxt = exMessage.getString("MSGTXT");
        if (Objects.equals("E", resType)) {
            return "E:" + msgtxt;
        }
        customer.setSn(kunnr);
        // 生成sap客户
        SapCustomer sapCustomer = BeanUtils.convertMap2Bean(cusMap, SapCustomer.class);
        sapCustomer.setSapNo(customer.getSn()); // Sap客户编码
        createSapCustomer(sap, sapCustomer);
        sapCustomer.setCustomerId(customerId);
        saveOrUpdate(sapCustomer);
        List<SalesGroupContent> salesGroupContents = BeanUtils.convertMap2BeanList(salesGroups, SalesGroupContent.class);
        salesGroupContents.forEach(e -> {
            e.setSapCustomerId(sapCustomer.getId());
            e.setCrmCustomerId(customerId);
            e.setSapNo(sapCustomer.getSapNo());
            e.setCompanyCode(sapCustomer.getCompanyCode());
        });
        String res = freezeSapCustomer(salesGroups, sap);
        if (res.startsWith("E")) {
            return res;
        }
        salesGroupContentService.createOrUpdateEntities(salesGroupContents);
        customerService.updateEntity(customer);
        return "S:创建成功";
    }

    public void createSapCustomer(Map<String, Object> sap, SapCustomer sapCustomer) {
        sapCustomer.setCate(Optional.ofNullable(sap.get("KUKLA")).orElse("").toString()); //客户分类
        sapCustomer.setBusiness(Optional.ofNullable(sap.get("BRAN1")).orElse("").toString()); // 客户行业
        sapCustomer.setName(Optional.ofNullable(sap.get("NAME1")).orElse("").toString()); // 客户名称
        sapCustomer.setShortName(Optional.ofNullable(sap.get("SORTL")).orElse("").toString()); // 客户简称
        sapCustomer.setNature(Optional.ofNullable(sap.get("BRSCH")).orElse("").toString()); // 客户性质
        sapCustomer.setCompanyCode(Optional.ofNullable(sap.get("BUKRS")).orElse("").toString()); // 公司代码
        sapCustomer.setPriceProcess(Optional.ofNullable(sap.get("KALKS")).orElse("").toString()); // 定价过程
        sapCustomer.setCountry(Optional.ofNullable(sap.get("COUNTRY")).orElse("").toString()); // 国家
        sapCustomer.setProvince(Optional.ofNullable(sap.get("REGION")).orElse("").toString()); // 省份
        sapCustomer.setAccountGroup(Optional.ofNullable(sap.get("KTOKD")).orElse("").toString()); // 账户组
        sapCustomer.setSalesOrg(Optional.ofNullable(sap.get("VKORG")).orElse("").toString()); // 销售组织
        sapCustomer.setSalesDept(Optional.ofNullable(sap.get("VKBUR")).orElse("").toString()); // 销售部门
        sapCustomer.setChannel(Optional.ofNullable(sap.get("VTWEG")).orElse("").toString()); // 分销渠道
        sapCustomer.setProduGroup(Optional.ofNullable(sap.get("SPART")).orElse("").toString()); // 产品组
        sapCustomer.setDis(Optional.ofNullable(sap.get("KTGRD")).orElse("").toString()); // 账户分配
        sapCustomer.setTaxCate(Optional.ofNullable(sap.get("TAXKD")).orElse("").toString()); // 税分类
        sapCustomer.setPostalCode(Optional.ofNullable(sap.get("PSTLZ")).orElse("").toString()); // 邮编
    }

    private String freezeSapCustomer(List<Map<String, Object>> salesGroups, Map<String, Object> sapParam) throws JCoException {
        List<SalesGroupContent> salesGroupContents = BeanUtils.convertMap2BeanList(salesGroups, SalesGroupContent.class);
        // 冻结的销售组织目录
        List<SalesGroupContent> freezeList = salesGroupContents.stream().filter(e -> S.equals(e.getIsFreeze(), "1")).collect(Collectors.toList());
        if (!freezeList.isEmpty()) {
            sapParam.put("VKORG", S.join(BeanUtils.collectToList(freezeList, SalesGroupContent::getSalesGroup))); // 销售组织多‘,’分割
            sapParam.put("VTWEG", S.join(BeanUtils.collectToList(freezeList, SalesGroupContent::getDistributeChannel))); // 分销渠道
            sapParam.put("SPART", S.join(BeanUtils.collectToList(freezeList, SalesGroupContent::getProductionGroup))); // 产品组
            Map<String, Object> ext = new HashMap<>();
            ext.put("type", "freeze");
            JCoParameterList res = sapUtil.exe("ZFSD003", sapParam, ext);
            JCoStructure exMessage = res.getStructure("EX_MESSAGE");
            String resType = exMessage.getString("MSGTYPE");
            String msgtxt = exMessage.getString("MSGTXT");
            if (Objects.equals("E", resType)) {
                return "E:" + msgtxt;
            } else {
                return "S:冻结成功";
            }
        }
        return "S:无冻结目录";
    }

    @Override
    public SapCustomerEditVO getSameCompanySapCustomer(String customerName) {
        String tenantId = IamSecurityUtils.getCurrentTenantId();
        IamTenant tenant = iamTenantMapper.selectById(tenantId);
        QueryWrapper<SapCustomer> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", customerName).eq("company_code", tenant.getOaNum());
        ThreadLocalHolder.setIgnoreInterceptor();
        SapCustomerDetailVO detailVO = this.getViewObject(queryWrapper, SapCustomerDetailVO.class);
        if (detailVO == null) {
            return null;
        }
        SapCustomerEditVO editVO = new SapCustomerEditVO();
        editVO.setCustomer(detailVO);
        QueryWrapper<SalesGroupContent> qw = new QueryWrapper<>();
        qw.eq("sap_customer_id", detailVO.getId());
        ThreadLocalHolder.setIgnoreInterceptor();
        List<SalesGroupContent> entityList = salesGroupContentService.getEntityList(qw);
        editVO.setSalesGroups(entityList);
        entityList.forEach(e -> {
            e.setTenantId(null);
            e.setId(null);
        });
        detailVO.setTenantId(null);
        detailVO.setId(null);
        detailVO.setCustomerId(null);
        editVO.setCustomId(null);
        return editVO;
    }
}